package com.bayss.web.uresponse;

import com.bayss.core.DokoServerException;
import com.bayss.core.DokoServerExceptionFactor;
import com.bayss.core.entity.user.UserInfo;
import com.bayss.core.service.user.UserService;
import com.bayss.core.util.TokenUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

@Component
public class UserResolver implements HandlerMethodArgumentResolver {
    private static Logger logger = LogManager.getLogger();
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType() == UserResponse.class || parameter.getParameterType() == DeliverymanResponse.class;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);

        if (parameter.getParameterType() == UserResponse.class) {
            String openid = servletRequest.getHeader("openid");
            if (StringUtils.isBlank(openid)) {
                logger.error("认证失败，缺少openid标识");
                throw new DokoServerException(DokoServerExceptionFactor.MISSING_PARAM, "认证失败");//错误细节不暴露外部
            }
            UserInfo userInfo = userService.getUser(openid);
            if (userInfo == null) {
                throw new DokoServerException(DokoServerExceptionFactor.USER_NOT_EXIST);
            }
            return UserResponse.builder()
                    .userInfo(userInfo)
                    .openId(userInfo.getOpenId())
                    .uid(userInfo.getId())
                    .build();
        } else {
            String token = servletRequest.getHeader("token");// 从 http 请求头中取出 token
            if (StringUtils.isBlank(token)) {
                logger.error("认证失败，缺少token标识");
                throw new DokoServerException(DokoServerExceptionFactor.MISSING_PARAM, "认证失败");//错误细节不暴露外部
            }

            Integer deliverymanId = TokenUtils.getUserId(token, "deliveryman_id");
            return DeliverymanResponse.builder()
                    .deliId((long)deliverymanId)
                    .build();
        }
    }
}
